﻿using System.IO;
using System.Linq;
using System.Text;
using System.Xml;

namespace UwaySoft.EsheetServer.BizLogic
{
    public class XmlHelper
    {
        public static XmlNode ImportXmlNodeFromText(string text, ref XmlDocument xmlDoc)
        {
            xmlDoc.LoadXml(text);
            return xmlDoc.FirstChild;
        }

        public static XmlDocument ReadAsXmlDocument(string xmlText)
        {
            var reader = XmlReader.Create(new StringReader(SanitizeXmlString(xmlText)));
            var xmlDoc = new XmlDocument();
            xmlDoc.Load(reader);
            return xmlDoc;
        }

        public static XmlDocument OpenAsXmlDocument(string filePath)
        {
            var reader = new XmlTextReader(filePath) {WhitespaceHandling = WhitespaceHandling.All};
            var xmlDoc = new XmlDocument();
            xmlDoc.Load(reader);
            reader.Close();
            return xmlDoc;
        }

        public static XmlAttribute AddAttribute(XmlDocument xmlDocument, string name, string value)
        {
            var temp = xmlDocument.CreateAttribute(name);
            temp.Value = value;
            return temp;
        }

        public static XmlNode AddTextNode(XmlDocument xmlDocument, string name, string value)
        {
            var temp = xmlDocument.CreateNode(XmlNodeType.Element, name, "");
            temp.AppendChild(xmlDocument.CreateTextNode(value));
            return temp;
        }

        public static XmlNode AddCDataNode(XmlDocument xmlDocument, string name, string value)
        {
            var temp = xmlDocument.CreateNode(XmlNodeType.Element, name, "");
            temp.AppendChild(xmlDocument.CreateCDataSection(value));
            return temp;
        }

        public static string GetNodeValue(XmlNode node)
        {
            if (node == null || node.FirstChild == null)
                return string.Empty;
            return node.FirstChild.Value;
        }

        public static string SanitizeXmlString(string xml)
        {
            if (string.IsNullOrEmpty(xml))
            {
                return xml;
            }

            var buffer = new StringBuilder(xml.Length);

            foreach (var c in xml.Where(c => IsLegalXmlChar(c)))
            {
                buffer.Append(c);
            }

            return buffer.ToString();
        }

        public static bool IsLegalXmlChar(int character)
        {
            return
            (
                character == 0x9 || 
                character == 0xA || 
                character == 0xD ||
                (character >= 0x20 && character <= 0xD7FF) || 
                (character >= 0xE000 && character <= 0xFFFD) ||
                (character >= 0x10000 && character <= 0x10FFFF)
            );
        }
    }
}
